<template>
  <div class="dashboard">
    <el-row :gutter="20" style="margin-top: 20px; margin-right: 5px">
      <el-col :span="6">
        <el-card></el-card>
      </el-col>
      <el-col :span="18">
        <el-card></el-card>
      </el-col>
    </el-row>
    <el-row :gutter="20" style="margin-top: 20px; margin-right: 5px">
      <el-col :span="8">
        <el-card>
          <z-chart ref="costBarChart" :resizable="true"></z-chart>
        </el-card>
      </el-col>
      <el-col :span="8">
        <el-card>
          <z-chart ref="userLineChart" :resizable="true"></z-chart>
        </el-card>
      </el-col>
      <el-col :span="8">
        <el-card>
          <z-chart ref="salePieChart" :resizable="true"></z-chart>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import ZChart from "../components/chart/ZChart";
import dayjs from "dayjs";

export default {
  name: "Dashboard",
  components: { ZChart },
  data() {
    return {
      timer: null,
      allowPolling: false, // 控制是否轮询
    };
  },
  methods: {
    async drawCostBar() {
      const chart = this.$refs.costBarChart;
      const result = await this.$api.getCostData();
      chart.setOption({
        grid: {
          left: 60,
        },
        title: {
          text: "收入与成本",
        },
        legend: { data: ["收入", "成本"], right: 0 },
        xAxis: {
          data: Object.keys(result).map((item) =>
            dayjs(Number(item)).format("YYYY-MM-DD")
          ),
        },
        yAxis: {},
        series: [
          {
            name: "收入",
            data: Object.values(result).map((item) => item.earn),
            type: "bar",
          },
          {
            name: "成本",
            data: Object.values(result).map((item) => item.cost),
            type: "bar",
          },
        ],
      });
    },
    async drawSalePie() {
      const chart = this.$refs.salePieChart;
      const result = await this.$api.getSaleData();
      const data = Object.entries(result)
        .map((item) => ({
          name: item[0],
          value: item[1],
        }))
        .sort((a, b) => b.value - a.value)
        .slice(0, 5);
      const legendData = data.map((item) => item.name);
      chart.setOption({
        title: {
          text: "销售TOP5",
        },
        color: ["orange", "skyblue", "gold", "orangered", "yellowgreen"],
        tooltip: { formatter: "{b}: {c} ({d}%)" },
        legend: {
          data: legendData,
          top: 30,
        },
        series: [
          {
            type: "pie",
            selectedMode: "single",
            center: ["50%", "60%"],
            radius: ["60%"],
            labelLine: {
              show: false,
            },
            label: {
              show: false,
            },
            emphasis: {
              label: {
                show: true,
              },
            },
            data,
          },
        ],
      });
    },
    async drawUserLine() {
      const chart = this.$refs.userLineChart;
      const result = await this.$api.getUserData();
      const time = Object.keys(result).map((item) =>
        dayjs(Number(item)).format("HH:mm:ss")
      );
      const increase = Object.values(result).map((item) => item.increase);
      chart.setOption({
        grid: {
          left: 60,
        },
        color: ["red", "yellow", "skyblue"],
        xAxis: {
          data: time,
        },
        yAxis: {},
        tooltip: {},
        series: [
          {
            type: "line",
            smooth: true,
            name: "用户增长数",
            data: increase,
          },
          {
            type: "line",
            smooth: true,
            name: "当前用户在线数",
            data: Object.values(result).map((item) => item.online),
          },
          {
            type: "line",
            smooth: true,
            name: "用户注册总数(K)",
            data: Object.values(result).map((item) => ~~(item.total / 1000)),
          },
        ],
      });
    },
    polling() {
      // 轮询方法
      if (!this.allowPolling) return;
      clearTimeout(this.timer);
      this.drawUserLine();
      this.timer = setTimeout(async () => {
        try {
          await this.drawUserLine(this.polling());
        } catch (e) {
          this.endPolling();
        }
      }, 2000);
    },
    startPolling() {
      // 开启轮询
      this.allowPolling = true;
      this.polling();
    },
    endPolling() {
      // 结束轮询
      clearTimeout(this.timer);
      this.timer = nul;
      this.allowPolling = false;
    },
  },

  mounted() {
    this.drawCostBar();
    this.drawSalePie();
    this.startPolling();
  },
  beforeDestroy() {
    this.endPolling();
  },
  activated() {
    this.startPolling();
  },
  deactivated() {
    this.endPolling();
  },
};
</script>

<style scoped>
.el-card ::v-deep.el-card__body {
  box-sizing: border-box;
  height: 300px;
}
</style>